﻿#include "framework.h"
#include "Const.h"
#include "SnakeBody.h"

// 函数声明
static void SnakeBody_Delete(SnakeBody**);
static void SnakeBody_Draw(SnakeBody*);
static void SnakeBody_Erase(SnakeBody*);
static void SnakeBody_SetType(SnakeBody*, SnakeBodyType);

/**
 * 创建蛇身。
 * @param drawer    绘图者
 * @param point     位置
 * @param type      类型
 * @return 蛇身
 */
SnakeBody* New_SnakeBody(HDC drawer, POINT point, SnakeBodyType type) {
    SnakeBody* snakeBody = (SnakeBody*)calloc(1, sizeof(SnakeBody));

    // 初始化数据
    snakeBody->mDrawer = drawer;
    snakeBody->mPosition = point;

    // 初始化函数
    snakeBody->deleteSelf = SnakeBody_Delete;
    snakeBody->draw = SnakeBody_Draw;
    snakeBody->erase = SnakeBody_Erase;
    snakeBody->setType = SnakeBody_SetType;

    // 设置类型
    snakeBody->setType(snakeBody, type);

    // 画自身
    snakeBody->draw(snakeBody);

    return snakeBody;
}

/**
 * 删除蛇身。
 * @param snakeBody 蛇身
 */
static void SnakeBody_Delete(SnakeBody** snakeBody) {
    (*snakeBody)->erase(*snakeBody);
    DeleteObject((*snakeBody)->mBrush);
    free(*snakeBody);
    *snakeBody = NULL;
}

/**
 * 画蛇身。
 * @param snakeBody 蛇身
 */
static void SnakeBody_Draw(SnakeBody* snakeBody) {
    SelectObject(snakeBody->mDrawer, snakeBody->mBrush);
    Ellipse(snakeBody->mDrawer, snakeBody->mPosition.x * GRID_SIZE, snakeBody->mPosition.y * GRID_SIZE,
        snakeBody->mPosition.x * GRID_SIZE + GRID_SIZE, snakeBody->mPosition.y * GRID_SIZE + GRID_SIZE);
}

/**
 * 将蛇身从原来的位置中抹除。
 * @param snakeBody    蛇身
 */
static void SnakeBody_Erase(SnakeBody* snakeBody) {
    RECT rect = { 0 };
    rect.left = snakeBody->mPosition.x * GRID_SIZE;
    rect.top = snakeBody->mPosition.y * GRID_SIZE;
    rect.right = snakeBody->mPosition.x  * GRID_SIZE + GRID_SIZE;
    rect.bottom = snakeBody->mPosition.y  * GRID_SIZE + GRID_SIZE;
    SetBkColor(snakeBody->mDrawer, GAME_BOARD_COLOR);
    ExtTextOut(snakeBody->mDrawer, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
}

/**
 * 设置蛇身的类型。
 * @param snakeBody 蛇身
 * @param type      类型
 */
static void SnakeBody_SetType(SnakeBody* snakeBody, SnakeBodyType type) {
    DeleteObject(snakeBody->mBrush);
    if (type == SNAKE) {
        snakeBody->mBrush = CreateSolidBrush(SNAKE_COLOR);
    } else {
        snakeBody->mBrush = CreateSolidBrush(APPLE_COLOR);
    }
}
